package com.cipe.cmrs.controllers;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import com.cipe.cmrs.converter.DateEditor;
import com.cipe.cmrs.model.User;
import com.cipe.cmrs.util.Constants;
import com.cipe.cmrs.util.CustomTimestampEditor;

public class BaseController implements Serializable {

	private static final long serialVersionUID = -4933050612370312999L;
	public static final String MESSAGES_KEY = "successMessages";
	public static final String ERROR_KEY = "errors";
	protected Logger logger = LoggerFactory.getLogger(getClass());
	protected static final String DEFAULT_SUBMIT_NAME = "action";
	private MessageSourceAccessor messageSourceAccessor;
	private String formView;
	private String successView;

    @Autowired
    public void setMessageSourceAccessor(MessageSourceAccessor messageSourceAccessor) {
        this.messageSourceAccessor = messageSourceAccessor;
    }

	public String getFormView() {
		return formView;
	}

	public void setFormView(String formView) {
		this.formView = formView;
	}

	public String getSuccessView() {
		return successView;
	}

	public void setSuccessView(String successView) {
		this.successView = successView;
	}

	@SuppressWarnings("unchecked")
	public boolean hasError(HttpServletRequest request) {
		List<String> errors = (List<String>) request.getSession().getAttribute(ERROR_KEY);
		return CollectionUtils.isNotEmpty(errors);
	}

	@SuppressWarnings("unchecked")
	public void saveError(HttpServletRequest request, String error) {
		List<String> errors = (List<String>) request.getSession().getAttribute(ERROR_KEY);
		if (errors == null) {
			errors = new ArrayList<String>();
		}
		errors.add(error);
		request.getSession().setAttribute(ERROR_KEY, errors);
	}
	
	public void saveError(HttpServletRequest request, List<ObjectError> errors) {
		for (ObjectError err : errors) {
			saveError(request, err.getDefaultMessage());
		}
	}

	@SuppressWarnings("unchecked")
	public void saveMessage(HttpServletRequest request, String msg) {
		List<String> messages = (List<String>) request.getSession().getAttribute(MESSAGES_KEY);

		if (messages == null) {
			messages = new ArrayList<String>();
		}

		messages.add(msg);
		request.getSession().setAttribute(MESSAGES_KEY, messages);
	}

	public Integer getUserId(HttpSession session) {
		return (Integer) session.getAttribute(User.LOGGED_IN_USER_KEY);
	}

	public Integer getUserId(HttpServletRequest request) {
		return (Integer) request.getSession().getAttribute(User.LOGGED_IN_USER_KEY);
	}

	@InitBinder
	public void initBinder(WebDataBinder binder) {
//		SimpleDateFormat dateFormat = new SimpleDateFormat(Constants.dateFormat);
//		dateFormat.setLenient(false);
		binder.registerCustomEditor(Timestamp.class, new CustomTimestampEditor(Constants.DefaultDateFormat));
		
    	binder.registerCustomEditor(java.util.Date.class, new DateEditor(null, Constants.DefaultDateFormat));
    	
	}

	public String getText(String msgKey) {
		return getText(msgKey, null);
	}

	/**
	 * Convenience method for getting a i18n key's value. Calling
	 * getMessageSourceAccessor() is used because the RequestContext variable is
	 * not set in unit tests b/c there's no DispatchServlet Request.
	 * 
	 * @param msgKey
	 * @param locale
	 *            the current locale
	 * @return
	 */
	public String getText(String msgKey, Locale locale) {
		return messageSourceAccessor.getMessage(msgKey, locale);
	}

	/**
	 * Convenient method for getting a i18n key's value with a single string
	 * argument.
	 * 
	 * @param msgKey
	 * @param arg
	 * @param locale
	 *            the current locale
	 * @return
	 */
	public String getText(String msgKey, String arg, Locale locale) {
		return getText(msgKey, new Object[] { arg }, locale);
	}

	/**
	 * Convenience method for getting a i18n key's value with arguments.
	 * 
	 * @param msgKey
	 * @param args
	 * @param locale
	 *            the current locale
	 * @return
	 */
	public String getText(String msgKey, Object[] args, Locale locale) {
		return messageSourceAccessor.getMessage(msgKey, args, locale);
	}
}
